home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Users Group Library 1996 July / C-C++ Users Group Library July 1996.iso / listings / v_12_01 / yuen / csemq.cpp < prev    next >
Encoding:
C/C++ Source or Header  |  1993-11-10  |  1.8 KB  |  104 lines

  1. #include <stdlib.h>
  2. #include "csemq.hpp"
  3.  
  4.  
  5. /* Constructor */
  6. Csemq::Csemq()
  7. {
  8.   sem = 0L;
  9.   priority = CSC_NO_THREAD;
  10. }
  11.  
  12.  
  13. /* Another Constructor */
  14. Csemq::Csemq(long lValue)
  15. {
  16.   sem = lValue;
  17.   priority = CSC_NO_THREAD;
  18. }
  19.  
  20.  
  21. /* Used to return a thread for execution based on a
  22.    round-robin-like scheduling algorithm */
  23. int Csemq::Dequeue()
  24. {
  25.   int nTask = CSC_NO_THREAD;
  26.   long task;
  27.  
  28.   long tmp;
  29.   int i;
  30.   
  31.   if (sem < 0)
  32.     {
  33.     //this implements a somewhat round-robin scheduling algorithm
  34.     task = _lrotl(1, priority + 1);
  35.     tmp = sem & ~CSC_IDLE;
  36.  
  37.     /* scan the semaphore queue structure bit-by-bit */
  38.     for (i = 0; i < CSC_NO_THREAD + 1; i++)
  39.       {
  40.       if (task & tmp)
  41.         break;
  42.       else
  43.         task = _lrotl(task, 1);
  44.       }
  45.     
  46.     sem &= ~task;
  47.     if (sem == CSC_IDLE)
  48.       sem = 0;
  49.  
  50.     if (i <= CSC_NO_THREAD)
  51.       nTask = long (i + priority + 1) % 32L;
  52.       
  53.     }
  54.     
  55.   priority = nTask; 
  56.    
  57.   return (nTask);
  58. }
  59.  
  60.  
  61. /* Used to put a thread in the semaphore queue */
  62. void Csemq::Enqueue(int nThread)
  63. {
  64.   if ((nThread <= CSC_NO_THREAD) || (sem <= 0))
  65.     {
  66.     sem |= (1L << nThread) | CSC_IDLE ;
  67.     }
  68. }
  69.  
  70.  
  71. /* Used to update the semaphore count by the specified
  72.    amount */
  73. void Csemq::UpdateCount(long lValue)
  74. {
  75.   long lTmp;
  76.   
  77.   if (sem >= 0)
  78.     {
  79.     lTmp = sem + lValue;
  80.     if (lTmp >= 0)
  81.       sem = lTmp;
  82.     }
  83. }
  84.  
  85.  
  86. /* Used to return an indicator to the caller telling
  87.    it if the semaphore structure is a counter or a queue */
  88. csemq_type Csemq::GetType()
  89. {
  90.   csemq_type nType = CST_COUNT;
  91.   
  92.   if (sem < 0)
  93.     nType = CST_QUEUE;
  94.     
  95.   return (nType); 
  96. }
  97.  
  98.  
  99. /* Used to get the count of a semaphore */
  100. long Csemq::GetCount()
  101. {
  102.   return (sem);
  103. }
  104.